<?php
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
namespace api\v1\controller;

use think\facade\Db;
use think\Validate;
use cmf\controller\RestBaseController;
use api\v1\service\UserPublicService;
use think\exception\ValidateException;

class PublicController extends RestBaseController
{
    public function test1(){
        dump(config('app'));
    }

    /**
     * 用于微信小程序登录验证
     */
    public function wxAppLogin()
    {
        /** 微信小程序  */
        $appId = "wx85eb5c489516acbd";
        $appSecret = "48a453de8f1fb420a0520fbe983f8da7";
        $grant_type = "authorization_code";

        $validate = new Validate();
        $validate->rule([
            'code'           => 'require',
        ]);
        $validate->message([
            'code.require'           => '缺少参数code!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }

        $code          = $data['code'];

        $in_appId = $this->request->header('XX-Wxapp-AppId');
        //var_dump($appId);
        //var_dump($in_appId);
        if (strcmp($in_appId, $appId)) {
            $this->error('appId不一致！');            //与本程序使用appId不一致
        }

        $deviceType = $this->request->header('XX-Device-Type');
        if (empty($deviceType)) {
            $this->error('需要有header XX-Device-Type字段!');
        }
        if (!in_array($deviceType, $this->allowedDeviceTypes)) {
            $this->error('header XX-Device-Type字段值不符合!');
        }
        $this->deviceType = $deviceType;

        $response = cmf_curl_get("https://api.weixin.qq.com/sns/jscode2session?appid=$appId&secret=$appSecret&js_code=$code&grant_type=$grant_type");

        $response = json_decode($response, true);
        if (!empty($response['errcode'])) {
            $this->error('操作失败!');
        }

        //var_dump($response);
        /**
         * array(3) {
         * ["session_key"]=>
         * string(24) "HwDXgYelFPdWmOTd2rrFDA=="
         * ["openid"]=>
         * string(28) "oCS-o5HTEfhKVjL9EwtOAC_Zk760"
         * ["unionid"]=>
         * string(28) "opKXO61L5ZYgdvwEoOiw35bCIYCs"    //同一个开放平台添加的web页和小程序，获得的unionid是一样的
         * }
         */
        $unionid = '';      //当前小程序已绑定到微信开放平台账号下才会返回。

        $openid     = $response['openid'];
        $sessionKey = $response['session_key'];
        if (isset($response['unionid'])) {
            $unionid = $response['unionid'];        //当前小程序已绑定到微信开放平台账号下才会返回。
        }


        //$pc      = new WXBizDataCrypt($appId, $sessionKey);
        //$errCode = $pc->decryptData($data['encrypted_data'], $data['iv'], $wxUserData);

        //if ($errCode != 0) {
        //    $this->error('操作失败!');
        //}

        $findThirdPartyUser = Db::name("third_party_user")
            ->where('openid', $openid)
            ->where('app_id', $appId)
            ->whereOr('union_id', $unionid)
            ->find();

        $currentTime = time();
        $ip          = $this->request->ip(0, true);

        //$wxUserData['sessionKey'] = $sessionKey;
        //unset($wxUserData['watermark']);

        if ($findThirdPartyUser) {
            $userId = $findThirdPartyUser['user_id'];
            $token  = cmf_generate_user_token($findThirdPartyUser['user_id'], 'wxapp');

            $userData = [
                'union_id' => $unionid,
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
                'login_times'     => Db::raw('login_times+1'),
                //'more'            => json_encode($wxUserData)
            ];

            //if (isset($wxUserData['unionId'])) {
            //    $userData['union_id'] = $wxUserData['unionId'];
            //}

            Db::name("third_party_user")
                ->where('openid', $openid)
                ->where('app_id', $appId)
                ->update($userData);
        } else {

            //TODO 使用事务做用户注册
            $userId = Db::name("user")->insertGetId([
                'create_time'     => $currentTime,
                'user_status'     => 1,
                'user_type'       => 2,
                //'sex'             => $wxUserData['gender'],
                //'user_nickname'   => $wxUserData['nickName'],
                //'avatar'          => $wxUserData['avatarUrl'],
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
            ]);

            Db::name("third_party_user")->insert([
                'openid'          => $openid,
                'user_id'         => $userId,
                'third_party'     => 'wxapp',
                'app_id'          => $appId,
                'last_login_ip'   => $ip,
                'union_id'        => empty($unionid) ? '' : $unionid,
                //'union_id'        => isset($wxUserData['unionId']) ? $wxUserData['unionId'] : '',
                'last_login_time' => $currentTime,
                'create_time'     => $currentTime,
                'login_times'     => 1,
                'status'          => 1,
                //'more'            => json_encode($wxUserData)
            ]);

            $token = cmf_generate_user_token($userId, 'wxapp');
        }

        $user = Db::name('user')->where('id', $userId)->find();

        if (!empty($user)) {
            $this->user     = $user;
            $this->userId   = $user['id'];
            $this->userType = $user['user_type'];
            $this->success("登录成功!", ['token' => $token, 'user' => $user]);
        } else {
            $this->error('没有找到匹配用户！');
        }
    }

    //https://x.kjdll.com/wxapp/index/reg?name=xiongyi&password1=123&mobile=13517246847&openid=123
    public function reg()
    {
        $data = $this->request->param();
        //$nickname = $this->request->param('nickname', '');
        //$sfzhm = $this->request->param('idcard','');
        //$password1 = $this->request->param('password1', '');
        //$password2 = $this->request->param('password2', '');
        //$mobile = $this->request->param('mobile');
        //$mail = $this->request->param('mail','');
        //$openid = $this->request->param('openid');
        /*$data = [
            'name' => $nickname,
            'sfzhm' => $sfzhm, 
            'password' => $password1, 
            'password2' => $password2,
            'mobile' => $mobile, 
            'openid' => $openid,
            'mail' => $mail
        ];*/
        //var_dump($data);
        // 手动验证
        //$validate = new \think\Validate;
        /*$validate->rule('nickname', 'require|min:4|max:16')
            ->rule([
                'mail' => 'email',
                'mobile' => 'mobile',
                'password1' => 'require|min:6|max:16',
                'password2' => 'require|confirm:password1',
                'openid' => 'require',
            ]);
        if (!$validate->check($data)) {
            //$this->error($validate->getError());
            $j = [
                'code'                  => 0,
                'errcode'               => 0,
                'msg'                   => $validate->getError(),
                'data_describe'         => '',
                'data'                  => null,
            ];
            return $j;
        }
        */
        $j = cjson(400, 0, 400, '', 'data返回空');

        if ($data['openid'] == '' || is_null($data['openid'])) {
            $j = cjson(400, '', 400, '无微信openid,刷新页面重试', '用户注册失败');
            return $j;
        }

        $wxModel = new WxModel();
        $re = $wxModel->reg($data);

        //var_dump($re);

        if ($re['data']) {
            $userid = $re['data'];
            $j = cjson(200, $userid, 200, '用户注册成功', "data返回userid");
        } else {
            $j = cjson(400, 0, 400, $re['msg'], 'data返回空');
        }

        return $j;
    }

    //https://x.kjdll.com/api/wxapp/index/test?openid=oCS-o5HTEfhKVjL9EwtOAC_Zk760
    public function test()
    {
        $u = "test";
        return $this->success('test', $u);
    }

    //https://x.kjdll.com/api/wxapp/index/onlogin?code=1
    //老的，已废弃
    public function del_onlogin()
    {
        $code = $this->request->param('code', '');
        //var_dump("code:");
        //var_dump($code);
        $t = [
            $this->url_code2Session,
            "?",
            "appid=$this->appid&",
            "secret=$this->secret&",
            "js_code=$code&",
            "grant_type=$this->grant_type"
        ];
        $url = implode("", $t);

        $s = file_get_contents($url);           //向微信API发送get请求
        //var_dump($s);
        //string(82) "{"session_key":"nXPNpbzI4wwmpSCzppmeSQ==","openid":"oCS-o5HTEfhKVjL9EwtOAC_Zk760"}" 
        $jsondecode = json_decode($s);          //对JSON格式的字符串进行解码
        //var_dump("jsondecode:");
        //var_dump($jsondecode);
        //object(stdClass)#44 (2) { ["session_key"]=> string(24) "nXPNpbzI4wwmpSCzppmeSQ==" ["openid"]=> string(28) "oCS-o5HTEfhKVjL9EwtOAC_Zk760" }
        $array = get_object_vars($jsondecode);  //转换成数组
        //var_dump("get_object_vars");
        //var_dump($array);
        //array(2) { ["session_key"]=> string(24) "nXPNpbzI4wwmpSCzppmeSQ==" ["openid"]=> string(28) "oCS-o5HTEfhKVjL9EwtOAC_Zk760" }

        //注意，如果接口报错，则会有errcode。如果接口正确，则不会有errcode和errmsg
        if (array_key_exists('errcode', $array)) {
            $errcode = $array['errcode'];
            $errmsg = $array['errmsg'];
            if ($errcode != 0) {
                $j = cjson($errcode, '', $errcode, $errmsg, '微信api接口auth.code2Session报错');
                return $j;
            }
        }

        $openid = $array['openid'];
        //return json($openid);
        //var_dump("微信openid:");var_dump($openid);var_dump("<br>");

        $session_key = $array['session_key'];    //session_key 	string 	会话密钥
        //return json($array['session_key']);//输出openid

        $wxModel = new wxModel();
        $user = $wxModel->login($openid);
        //var_dump("wxModel->login:");var_dump($user);var_dump("<br>");
        if ($user == 0) {
            $j = cjson(401, $openid, 401, '用户未注册', 'data返回openid');
            return $j;
        } else if ($user == -1) {
            $j = cjson(403, $openid, 403, '用户状态错误或无权限，限制登陆', 'data返回openid');
            return $j;
        }
        //var_dump("userid:");var_dump($user);

        if ($user['id'] > 0) {
            $wxuser = [
                //'openid' => $openid,
                //'session_key' => $session_key,
                'name' =>   $user['name'],
                'id' => $user['id'],
                'roleIdList' => $user['roleIdList'],
                'mobile' => $user['mobile'],
                'userLevel' => $user['userlevel']
            ];

            //存在此微信用户，开始session
            session_start([
                'cookie_lifetime' => 86400,     // 设置 cookie 的有效时间为 1 天
                //'read_and_close'  => true,    //不能用这个配置，否则微信小程序的登录态无效
            ]);
            $sessionid = session_id();      //取得session_id

            //取用户平台
            $where['user_id'] = $wxuser['id'];
            $query = Db::name('xmgl_zzjg_user')->where($where)->value('zzjg_id');
            if (!is_null($query)) {
                $wxuser['zzjg_id'] = $query;
            } else {
                $wxuser['zzjg_id'] = 0;
            }

            $_SESSION['wxuser'] = $wxuser;    //写入SESSION
            //session('wxuser',$wxuser);  //设置session
            $j = cjson(200, $sessionid, 200, '成功', 'data返回sessionid,额外参数是userid和微信openid');
            return $j;
        } else {
            $j = cjson(401, $openid, 401, '用户未注册或未授权', 'data返回openid');
            return $j;
        }
    }

    /**
     * WEB页微信扫码登录后 ，注册新用户
     */
    public function webUserReg()
    {
        $p = $this->request->param();
        //dump($p);
        /**
         * 传入参数
         * {"user_login":"姓名","mobile":"13217243213","sex":"男","birthday":"1741449600","email":"34@qq.com","pass":"","checkPass":"","signature":"个性签名","zzjgValue":["2","6"],"roleValue":["10","3"]}
         */

        $zzjgValue = $this->request->param('zzjgValue/a', []);
        $roleValue = $this->request->param('roleValue/a', []);

        $p['zzjgValue'] = $zzjgValue;
        $p['roleValue'] = $roleValue;

        try {
            validate([
                'user_login'  => 'string|min:2|max:12',
                'mobile'   => 'mobile',
                'sex'  => 'number|between:1,2',
                //'nickname'   => 'chsAlphaNum',      //注意数据库表用的是user_nickname
                'avatar'   => 'require',
                'union_id'   => 'string',
                'openid'   => 'string',
                'app_id'   => 'string',
                'access_token'   => 'string',
                'expire_time'   => 'number',
                'third_party'   => 'string',
                'email'  => 'email',                     //注意数据库表用的是user_email
                //'zzjgValue'   => 'array',
                //'roleValue'   => 'array',
                //'pass'   => 'require|confirm:checkPass',
            ])->message([
                //'user_login.chsAlphaNum' => '姓名只能由汉字字母和数字组成',
                'mobile.mobile'     => '手机号不正确',
                'sex.between'   => '性别除了男女没有别的选择',
                'birthday'      => '日期格式不正确',
                'email'        => '邮箱格式错误',
                //'pass.confirm' => '二次密码不一致'
            ])->check($p);
        } catch (ValidateException $e) {
            // 验证失败 
            //dump($e->getError()); // 输出错误信息
            //dump($e->getKey()); // 验证错误的字段名
            $this->error($e->getError());
        }

        $p['birthday'] = strtotime($p['birthday']);     //js格式日期转unix时间
        if (!$p['birthday']) $this->error('日期转换错误！');

        try {
            $ups = new UserPublicService;
            $res = $ups->updateUser($p);
        } catch (\Exception $e) {
            $this->error($e->getMessage(),$e->getCode());
        }
        $this->success('用户注册', $res);
    }
}
